package LDraw.Support; import java.util.ArrayList; import java.util.HashMap; import java.util.StringTokenizer; import javax.media.opengl.GL2; import javax.swing.undo.UndoManager; import Command.LDrawBFCCommand; import Command.LDrawColor; import Command.LDrawComment; public class LDrawMetaCommand extends LDrawDirective { /** * @uml.property name="commandString" */ String commandString; public LDrawMetaCommand() { this.commandString = ""; } // ========== initWithLines:inRange:parentGroup: // ================================ // // Purpose: Returns the LDraw directive based on lineFromFile, a single line // of LDraw code from a file. // // directive should have the format: // // 0 command... // // This method determines and returns a subclass instance for known // meta-commands. As such, the instance returned will always be of // a different class, and thus will always be a different instance // than the receiver. // // ============================================================================== public LDrawDirective initWithLines(ArrayList<String> lines, Range range, DispatchGroup parentGroup) { super.init(); LDrawDirective directive = null; String parsedField = null; String firstLine = lines.get(range.getLocation()); int lineCode = 0; boolean gotLineCode = false; int metaLineStart = 0; StringTokenizer strTokenizer = new StringTokenizer(firstLine); // A malformed part could easily cause a string indexing error, which // would // raise an exception. We don't want this to happen here. try { // Read in the line code and advance past it. try { lineCode = Integer.parseInt(strTokenizer.nextToken()); gotLineCode = true; } catch (Exception e) { gotLineCode = false; } if (gotLineCode == true && lineCode == 0) { // The first word of a meta-command should indicate the command // itself, and thus the syntax of the rest of the line. However, // the // first word might not be a recognized command. It might not // even // be anything. "0\n" is perfectly valid LDraw. // [scanner scanCharactersFromSet:[NSCharacterSet // whitespaceCharacterSet] intoString:null]; // metaLineStart = [scanner scanLocation]; // metaLineStart = firstLine.indexOf(" ")+1; // [scanner scanUpToCharactersFromSet:[NSCharacterSet // whitespaceCharacterSet] intoString:&parsedField]; if(strTokenizer.hasMoreTokens()) parsedField = strTokenizer.nextToken(); else parsedField =""; // Comment? if (parsedField.equals(LDrawKeywords.LDRAW_COMMENT_SLASH) || parsedField .equals(LDrawKeywords.LDRAW_COMMENT_WRITE) || parsedField .equals(LDrawKeywords.LDRAW_COMMENT_PRINT)) { directive = new LDrawComment(); ((LDrawComment) directive).finishParsing(strTokenizer); } // Color Definition? else if (parsedField .equals(LDrawKeywords.LDRAW_COLOR_DEFINITION)) { directive = new LDrawColor(); ((LDrawColor) directive).finishParsing(strTokenizer); } // else if (parsedField.equals(LDrawKeywords.MOCBUILDER_CUSTOM_META)) { directive = new LDrawCustomMetaCommand(); String command = firstLine.substring(metaLineStart); ((LDrawCustomMetaCommand)directive).setStringValue(command); }else if (parsedField.equals(LDrawKeywords.LDRAW_BFC)) { directive = new LDrawBFCCommand(); ((LDrawBFCCommand)directive).finishParsing(strTokenizer); } if (directive == null) { // Didn't specifically recognize this metacommand. Create a // non-functional generic command to record its existence. directive = this; String command = firstLine.substring(metaLineStart); setStringValue(command); } } else if (gotLineCode == false) { // This is presumably an empty line, and the following will // incorrectly add a 0 linetype to it. directive = this;// [self retain]; String command = firstLine.substring(metaLineStart); setStringValue(command); } else { // nonzero linetype! throw new Exception("BricksmithParseException: " + "Bad metacommand syntax"); } } catch (Exception e) { System.out.println(String.format( "the meta-command %s was fatally invalid", lines.get(range.getLocation()))); System.out.println(String.format(" raised exception %s", e.getMessage())); } // The new directive should replace the receiver! return directive; }// end initWithLines:inRange: // ========== finishParsing: // ==================================================== // // Purpose: Subclasses override this method to finish parsing their specific // syntax once -[LDrawMetaCommand initWithLines:inRange:] // has determined which subclass to instantiate. // // Returns: YES on success; NO on a syntax error. // // ============================================================================== // public boolean finishParsing(NSScanner *)scanner // { // // LDrawMetaCommand itself doesn't have any special syntax, so we // shouldn't // // be getting any in this method. // return NO; // // }//end finishParsing: // #pragma mark - // #pragma mark DIRECTIVES // #pragma mark - // ========== draw:viewScale:parentColor: // ======================================= // // Purpose: Draws the part. // // ============================================================================== public void draw(GL2 gl2, HashMap<Integer, Boolean> optionsMask, float scaleFactor, LDrawColor parentColor) { // Nothing to do here. }// end draw:viewScale:parentColor: // ========== write // ============================================================= // // Purpose: Returns a line that can be written out to a file. // Line format: // 0 command... // // ============================================================================== public String write() { return String.format("%s", stringValue()); }// end write // #pragma mark - // #pragma mark DISPLAY // #pragma mark - // ========== browsingDescription // =============================================== // // Purpose: Returns a representation of the directive as a short string // which can be presented to the user. // // ============================================================================== public String browsingDescription() { // return NSLocalizedString(@"Unknown Metacommand", null); return commandString; }// end browsingDescription // ========== iconName // ========================================================== // // Purpose: Returns the name of image file used to display this kind of // object, or null if there is no icon. // // ============================================================================== public String iconName() { return "Unknown"; }// end iconName // ========== inspectorClassName // ================================================ // // Purpose: Returns the name of the class used to inspect this one. // // ============================================================================== public String inspectorClassName() { return "InspectionUnknownCommand"; }// end inspectorClassName // #pragma mark - // #pragma mark ACCESSORS // #pragma mark - // ========== setStringValue: // =================================================== // // Purpose: updates the basic command string. // // ============================================================================== public void setStringValue(String newString) { commandString = newString; }// end setStringValue: // ========== stringValue // ======================================================= // // Purpose: // // ============================================================================== public String stringValue() { return commandString; }// end stringValue // #pragma mark - // #pragma mark UTILITIES // #pragma mark - // ========== registerUndoActions // =============================================== // // Purpose: Registers the undo actions that are unique to this subclass, // not to any superclass. // // ============================================================================== public void registerUndoActions(UndoManager undoManager) { // [super registerUndoActions:undoManager]; // // [[undoManager prepareWithInvocationTarget:self] setStringValue:[self // stringValue]]; // [undoManager setActionName:NSLocalizedString(@"UndoAttributesLine", // null)]; // (unused for this class; a plain "Undo" will probably be less // confusing.) }// end registerUndoActions: }